import router from "./router";
import store from "./store";
import { Notify } from "vant";
import NProgress from "nprogress"; // progress bar
import "nprogress/nprogress.css"; // progress bar style
import { getToken } from "@/utils/auth"; // get token from cookie
import getPageTitle from "@/utils/get-page-title";

NProgress.configure({ showSpinner: false }); // NProgress Configuration

const whiteList = ["/login"]; // no redirect whitelist

router.beforeEach(async (to, from, next) => {
	// start progress bar
	NProgress.start();
	// set page title
	document.title = getPageTitle(to.meta.title);

	const hasToken = getToken();
	if (hasToken) {
		if (to.path === "/login") {
			next({ path: "/" });
			NProgress.done();
		} else {
			if (to.path === "/login") {
				// if is logged in, redirect to the home page
				next({ path: "/" });
				NProgress.done();
			} else {
				// determine whether the user has obtained his permission roles through getInfo
				const hasRoles = store.getters.roles && store.getters.roles.length > 0;
				if (hasRoles) {
					next();
				} else {
					try {
						// get user info
						const { roles } = await store.dispatch("user/getInfo");
						// generate accessible routes map based on roles
						const accessRoutes = await store.dispatch("permission/generateRoutes", roles);
						// dynamically add accessible routes
						router.addRoutes(accessRoutes);
						next({ ...to, replace: true });
					} catch (error) {
						// remove token and go to login page to re-login
						await store.dispatch("user/resetToken");
						Notify({ type: "warning", message: error || "Has Error" });
						next(`/login?redirect=${to.path}`);
						NProgress.done();
					}
				}
			}
		}
	} else {
		/* has no token*/

		if (whiteList.indexOf(to.path) !== -1) {
			// in the free login whitelist, go directly
			next();
		} else {
			// other pages that do not have permission to access are redirected to the login page.
			next(`/login?redirect=${to.path}`);
			NProgress.done();
		}
	}
});

router.afterEach(() => {
	// finish progress bar
	NProgress.done();
});
